package xyz.xtt.pay.service.impl;

import static java.util.stream.Collectors.toMap;
import static java.util.stream.Collectors.toSet;
import static xyz.xtt.common.asset.AssertUtils.isNull;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.google.common.primitives.Longs;

import cn.hutool.core.thread.ThreadFactoryBuilder;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import xyz.xtt.asset.client.response.AssetAllInfoResponse;
import xyz.xtt.asset.client.response.AssetExtInfoResponse;
import xyz.xtt.asset.client.response.AssetInfoResponse;
import xyz.xtt.asset.client.response.AssetStaticResponse;
import xyz.xtt.asset.client.response.TransactionResponse;
import xyz.xtt.exchange.response.AssetAuditResponse;
import xyz.xtt.pay.api.dto.GetPayStatusRequest;
import xyz.xtt.pay.api.dto.PayAttach;
import xyz.xtt.pay.api.enums.PayOrderBusinessTypeEnum;
import xyz.xtt.pay.api.enums.PayOrderStatusEnum;
import xyz.xtt.pay.client.response.PayOrderResponse;
import xyz.xtt.pay.constants.ErrorMessage;
import xyz.xtt.pay.dto.PayCenterOrderStatusResponse;
import xyz.xtt.pay.entity.PayOrder;
import xyz.xtt.pay.entity.TblBusinessOrder;
import xyz.xtt.pay.enums.OrderTypeEnum;
import xyz.xtt.pay.mapper.PayOrderMapper;
import xyz.xtt.pay.response.TopConsumeResponse;
import xyz.xtt.pay.response.TopConsumeVo;
import xyz.xtt.pay.service.IInnerService;
import xyz.xtt.pay.service.IPayOrderService;
import xyz.xtt.pay.service.ITblBusinessOrderService;
import xyz.xtt.pay.support.PayCenterHttpService;
import xyz.xtt.pay.support.PayCenterV3HttpService;
import xyz.xtt.pay.vo.OrderVo;
import xyz.xtt.user.client.response.UserInfoResponse;

/**
 * <p>
 * 支付订单主表 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-02-10
 */
@Service
@Slf4j
public class PayOrderServiceImpl extends ServiceImpl<PayOrderMapper, PayOrder> implements IPayOrderService {

	private static String PrderCardName = "的实体卡片";

	private static final int CORE_THREAD_COUNT = Runtime.getRuntime().availableProcessors() * 2 + 1;
	private static final ThreadFactory THREAD_FACTORY = new ThreadFactoryBuilder().setNamePrefix("pay-order-service-thread-%d").build();
	private static final ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor(
			CORE_THREAD_COUNT, CORE_THREAD_COUNT, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(20), THREAD_FACTORY,
			new ThreadPoolExecutor.CallerRunsPolicy());

	@Autowired
	private PayOrderMapper payOrderMapper;
	@Autowired
	private IInnerService iInnerService;
	@Autowired
	private PayCenterV3HttpService payCenterV3HttpService;
	@Autowired
	private PayCenterHttpService payCenterHttpService;
	@Autowired
	private ITblBusinessOrderService iTblBusinessOrderService;

	/**
	 * 获取个人消费榜单
	 */
	@Override
	public TopConsumeResponse getHotConsume(Long uId) {
		// 查询 group by sum
		QueryWrapper<PayOrder> query = new QueryWrapper<>();
		query
				.eq("pay_status", 1)
				.groupBy("app_user_id")
				.select("app_user_id,sum(pay_money) as money")
				.gt("pay_money", 0)
				.orderByDesc("money")
				.last("limit 100");
		List<Map<String, Object>> maps = baseMapper.selectMaps(query);

		List<TopConsumeVo> list = new ArrayList<>();
		// 查询用户缓存 infoWithUserIdCache
		AtomicReference<Integer> count = new AtomicReference<>(0);
		AtomicReference<Boolean> isList = new AtomicReference<>(false);

		Set<Long> appUids = maps.stream().map(x -> x.get("app_user_id")).map(String::valueOf).map(Longs::tryParse).collect(toSet());
		List<UserInfoResponse> batchInfo = iInnerService.batchInfo(appUids);
		Map<Long, UserInfoResponse> userMap = batchInfo.stream().collect(toMap(UserInfoResponse::getAppUserId, Function.identity()));
		maps.forEach(x -> {
			Long appUserId = Long.valueOf(String.valueOf(x.get("app_user_id")));
			// 查询不是当前用户，并且没有定位到用户 位置+1
			if (!uId.equals(appUserId) && !isList.get()) {
				count.getAndSet(count.get() + 1);
			}
			if (uId.equals(appUserId)) {
				isList.set(true);
			}
			if (list.size() > 100) {
				return;
			}
			// 查询用户信息
			UserInfoResponse tblUser = userMap.get(appUserId);
			if (Objects.isNull(tblUser)) {
				return;
			}
			// 乘 3 四舍五入 取整
			BigDecimal money = BigDecimal.valueOf(((Number) x.get("money")).doubleValue());
			// money = money.multiply(new BigDecimal(3)).setScale(0,
			// BigDecimal.ROUND_HALF_UP);

			TopConsumeVo topConsumeVo = new TopConsumeVo(tblUser.getNickname(), tblUser.getAvatarUri(), appUserId, money.toString(), "", tblUser.getGender());
			list.add(topConsumeVo);
		});

		// 查询自己信息
		TopConsumeVo myConsumeVo = getMyConsume(uId);
		if (Objects.nonNull(myConsumeVo)) {
			Integer num = count.get() + 1;
			String msg = num.toString();
			if (!isList.get()) {
				msg = "100+";
			}
			myConsumeVo.setMsg(msg);
		}
		return new TopConsumeResponse(list, myConsumeVo);
	}

	// 查询自己消息信息
	public TopConsumeVo getMyConsume(Long uId) {
		QueryWrapper<PayOrder> query = new QueryWrapper<>();
		query.eq("pay_status", 1).eq("app_user_id", uId).select("sum(pay_money) as money");
		Map<String, Object> map = this.getMap(query);
		UserInfoResponse tblUser = iInnerService.userInfo(uId);
		if (Objects.isNull(tblUser) || Objects.isNull(map)) {
			return null;
		}

		BigDecimal money = BigDecimal.valueOf(((Number) map.get("money")).doubleValue());
		money = money.multiply(new BigDecimal(3)).setScale(0, BigDecimal.ROUND_HALF_UP);
		return new TopConsumeVo(tblUser.getNickname(), tblUser.getAvatarUri(), uId, money.toString(), "", tblUser.getGender());

	}

	/**
	 * 获取我的订单信息
	 * 
	 * @param uid
	 * @param current
	 * @param pageSize
	 * @return
	 */
//	@Override
//	public List<OrderVo> getOrderList(Long uid, Integer current, Integer pageSize) {
//		current = Optional.ofNullable(current).filter(Objects::nonNull).filter(x -> x > 0).orElse(1);
//		String page = String.format("limit %d, %d", ((current - 1) * pageSize), pageSize);
//
//		LambdaQueryWrapper<TblAssetTransaction> query = new LambdaQueryWrapper<>();
//		query
//				.eq(TblAssetTransaction::getBuyerUserId, uid.toString())
//				.isNotNull(TblAssetTransaction::getBuyerUserId)
//				.orderByDesc(TblAssetTransaction::getOrderId)
//				.last(page);
//		List<TblAssetTransaction> tblAssetTransactions = tblAssetTransactionMapper.selectList(query);
//		List<OrderVo> orderVos = new ArrayList<>();
//
//		List<CompletableFuture<Pair<Long, Integer>>> queryPayStatusFutures = new ArrayList<>();
//		Map<Long, Integer> payOrderStatusMap = new HashMap<>();
//		for (TblAssetTransaction item : tblAssetTransactions) {
//			PayOrderStatusEnum payOrderStatusEnum = PayOrderStatusEnum.getByCode(item.getPayState());
//			if (Objects.equals(payOrderStatusEnum, PayOrderStatusEnum.UN_PAY)) {
//				CompletableFuture<Pair<Long, Integer>> task = CompletableFuture.supplyAsync(() -> {
//					ApiResult<Integer> result = assetClient
//							.getPayStatus(GetPayStatusRequest.builder().transactionId(item.getOrderId()).orderType(item.getOrderType()).build());
//					return result.isOk() ? Pair.of(item.getOrderId(), result.getData()) : null;
//				}, EXECUTOR);
//				queryPayStatusFutures.add(task);
//			}
//
//			OrderVo order = OrderVo.createOrderVo(item);
//			AssetBaseInfo assetBaseInfo = tblAssetService.baseInfo(item.getGoodsId());
//			;
//			if (!Objects.isNull(assetBaseInfo)) {
//				order.setGoodsName(assetBaseInfo.getAsset().getAssetName());
//				order.setAssetId(assetBaseInfo.getAsset().getId());
//				order.setGoodsId(assetBaseInfo.getAsset().getGoodsId());
//				order.setImageUrl(assetBaseInfo.getAssetStaticResource().getLogoUri());
//				order.setFirstType(assetBaseInfo.getAsset().getFirstType());
//				order.setSecondType(assetBaseInfo.getAsset().getSecondType());
//			}
//			orderVos.add(order);
//		}
//
//		if (!CollectionUtils.isEmpty(queryPayStatusFutures)) {
//			CompletableFuture<Void> allOf = CompletableFuture.allOf(queryPayStatusFutures.toArray(new CompletableFuture[0]));
//			try {
//				allOf.get(2, TimeUnit.SECONDS);
//			} catch (InterruptedException e) {
//				Thread.currentThread().interrupt();
//			} catch (ExecutionException e) {
//				log.error("get pay status error", e);
//			} catch (TimeoutException e) {
//				log.error("get pay status timeout", e);
//			}
//			queryPayStatusFutures.forEach(future -> {
//				Pair<Long, Integer> pair = future.getNow(null);
//				if (pair != null && pair.getRight() != null) {
//					payOrderStatusMap.put(pair.getLeft(), pair.getRight());
//				}
//			});
//
//			if (!CollectionUtils.isEmpty(payOrderStatusMap)) {
//				orderVos.forEach(order -> {
//					Integer status = payOrderStatusMap.get(order.getOrderId());
//					if (status != null) {
//						order.setPayStatus(status);
//					}
//				});
//			}
//		}
//
//		return orderVos;
//	}

	@Override
	public List<OrderVo> getOrderListByPayOrder(Long uid, Integer current, Integer pageSize) {
		current = Optional.ofNullable(current).filter(Objects::nonNull).filter(x -> x > 0).orElse(1);
		String page = String.format("limit %d, %d", ((current - 1) * pageSize), pageSize);

		LambdaQueryWrapper<PayOrder> query = new LambdaQueryWrapper<>();
		query.eq(PayOrder::getAppUserId, uid.toString()).orderByDesc(PayOrder::getCreateTime).last(page);
		List<PayOrder> payOrders = payOrderMapper.selectList(query);

		List<CompletableFuture<Pair<Long, Integer>>> queryPayStatusFutures = new ArrayList<>();
		List<OrderVo> orderVos = new ArrayList<>();
		Map<Long, Integer> payOrderStatusMap = new HashMap<>();

		Set<Long> businessIds = new HashSet<>();

		for (PayOrder item : payOrders) {
			PayOrderStatusEnum payOrderStatusEnum = PayOrderStatusEnum.getByCode(item.getPayStatus());
			if (Objects.equals(payOrderStatusEnum, PayOrderStatusEnum.UN_PAY)) {
				CompletableFuture<Pair<Long, Integer>> task = CompletableFuture.supplyAsync(() -> {
					Integer result = getPayStatus(GetPayStatusRequest.builder().payOrderId(item.getPayOrderId()).orderType(item.getBusinessType()).build());
					return Objects.nonNull(result) ? Pair.of(item.getPayOrderId(), result) : null;
				}, EXECUTOR);
				queryPayStatusFutures.add(task);
			}
			if (item.getBusinessType().equals(PayOrderBusinessTypeEnum.NFT_CARD.getCode())
					|| item.getBusinessType().equals(PayOrderBusinessTypeEnum.ASSET_WITH_PHYSICAL.getCode())) {
				businessIds.add(Long.valueOf(item.getBusinessRefId()));
			}
		}
		// 查询businessIds 卡片 对应的数据
		Map<Long, TblBusinessOrder> businessList = iTblBusinessOrderService.getBusinessByIds(businessIds);
		payOrders.forEach(x -> {
			OrderVo order = OrderVo.createOrderVo(x);
			PayOrderBusinessTypeEnum businessType = PayOrderBusinessTypeEnum.getByCode(x.getBusinessType());
			switch (businessType) {
			case NFT_CARD, ASSET_WITH_PHYSICAL -> setOrderByBusiness(order, businessList);
			case C_TO_C -> setCtoC(order, businessList);
			default -> setOrderByPayOrder(x, order);
			}
			orderVos.add(order);
		});

		if (!CollectionUtils.isEmpty(queryPayStatusFutures)) {
			CompletableFuture<Void> allOf = CompletableFuture.allOf(queryPayStatusFutures.toArray(new CompletableFuture[0]));
			try {
				allOf.get(2, TimeUnit.SECONDS);
			} catch (InterruptedException e) {
				Thread.currentThread().interrupt();
			} catch (ExecutionException e) {
				log.error("get pay status error", e);
			} catch (TimeoutException e) {
				log.error("get pay status timeout", e);
			}
			queryPayStatusFutures.forEach(future -> {
				Pair<Long, Integer> pair = future.getNow(null);
				if (pair != null && pair.getRight() != null) {
					payOrderStatusMap.put(pair.getLeft(), pair.getRight());
				}
			});

			if (!CollectionUtils.isEmpty(payOrderStatusMap)) {
				orderVos.forEach(order -> {
					Integer status = payOrderStatusMap.get(order.getOrderId());
					if (status != null) {
						order.setPayStatus(status);
					}
				});
			}
		}

		return orderVos;
	}

	private Object setCtoC(OrderVo order, Map<Long, TblBusinessOrder> businessList) {
		return null;
	}

	private void setOrderByBusiness(OrderVo order, Map<Long, TblBusinessOrder> businessList) {
		if (businessList.isEmpty()) {
			return;
		}
		TblBusinessOrder businessOrderDto = businessList.get(Long.valueOf(order.getBusinessRefId()));
		if (Objects.isNull(businessOrderDto)) {
			return;
		}

		// 处理名称显示
		String suffix = "";
		// 资产名称后面增加 实体卡
		if (order.getBusinessType().equals(PayOrderBusinessTypeEnum.NFT_CARD.getCode())) {
			suffix = PrderCardName;
		}
		order.setGoodsName(String.format("%s%s", businessOrderDto.getGoodsName(), suffix));
		order.setImageUrl(businessOrderDto.getGoodsImage());
		order.setTransportCompany(businessOrderDto.getTransportCompany());
		order.setTransportNo(businessOrderDto.getTransportNo());
		order.setPurchaseNum(businessOrderDto.getPurchaseNum());
	}

	private void setOrderByPayOrder(PayOrder x, OrderVo order) {
		AssetAllInfoResponse assetBaseInfo = this.getAssetInfoByPayOrder(x);
		if (!Objects.isNull(assetBaseInfo) && order != null) {
			order.setGoodsName(assetBaseInfo.getAsset().getAssetName());
			order.setAssetId(assetBaseInfo.getAsset().getId());
			order.setGoodsId(assetBaseInfo.getAsset().getGoodsId());
			order.setImageUrl(assetBaseInfo.getAssetStatic().getLogoUri());
			order.setFirstType(assetBaseInfo.getAsset().getFirstType());
			order.setSecondType(assetBaseInfo.getAsset().getSecondType());
			order.setPurchaseNum(1);
		}
	}

	private AssetAllInfoResponse getCtocInfo(PayOrder payOrder) {
		if (payOrder == null || payOrder.getBusinessRefId() == null) {
			return null;
		}
		AssetAuditResponse assetAuditInfo = iInnerService.assetAuditInfo(Longs.tryParse(payOrder.getBusinessRefId()));
		AssetInfoResponse asset = AssetInfoResponse
				.builder()
				.assetName(assetAuditInfo.getAssetName())
				.id(0L)
				.firstType(assetAuditInfo.getFirstType())
				.secondType(assetAuditInfo.getSecondType())
				.goodsId("0")
				.build();
		AssetExtInfoResponse assetExt = AssetExtInfoResponse.builder().build();
		AssetStaticResponse assetStatic = AssetStaticResponse.builder().logoUri(assetAuditInfo.getImgPath()).build();
		AssetAllInfoResponse build = AssetAllInfoResponse.builder().asset(asset).assetExt(assetExt).assetStatic(assetStatic).build();
		return build;
	}

	/**
	 * 获取支付订单中 资产信息
	 * 
	 * @param payOrder
	 * @return
	 */
	private AssetAllInfoResponse getAssetInfoByPayOrder(PayOrder payOrder) {
		// Early exit for null PayOrder
		if (Objects.isNull(payOrder)) {
			return null;
		}

		PayOrderBusinessTypeEnum businessType = PayOrderBusinessTypeEnum.getByCode(payOrder.getBusinessType());
		// More robust null checks and type checking
		if (businessType == null || businessType.getAttachClass() == null || !businessType.getAttachClass().equals(PayAttach.class)) {
			log.warn("Invalid business type or attach class for PayOrder: {}", String.valueOf(payOrder.getPayOrderId()));
			return null;
		}
		if (businessType == PayOrderBusinessTypeEnum.PERSONAL_MINT_V2) {
//			return getAssetBaseInfoFromPayOrder(payOrder); // Process PERSONAL_MINT_V2 even if businessAttach is null
			return getCtocInfo(payOrder); 
		}

		String businessAttach = payOrder.getBusinessAttach();
		// Handle null businessAttach, but still check for PERSONAL_MINT_V2
		if (Objects.isNull(businessAttach)) {
			log.warn("Missing businessAttach for PayOrder: {}", payOrder.getPayOrderId());
			return null;
		}

		PayAttach payAttach;
		try {
			payAttach = JSONObject.parseObject(businessAttach, PayAttach.class);
		} catch (Exception e) {
			log.error("Error parsing businessAttach for PayOrder: {}, Error: ", payOrder.getPayOrderId(), e);
			return null;
		}

		return switch (businessType) {
		case NORMAL, PERSONAL_MINT, ROSE_MINT, BUY_ASSET_1155, C_TO_C -> getAssetBaseInfoFromPayAttach(payAttach);
		case NFT_VIP_MONTH, NFT_VIP_SEASON, NFT_VIP_YEAR -> getAssetBaseInfoFromVIP(payAttach);
		default -> {
			log.warn("Unsupported business type: {} for PayOrder: {}", businessType, String.valueOf(payOrder.getPayOrderId()));
			yield null;
		}
		};
	}

	private AssetAllInfoResponse getAssetBaseInfoFromPayAttach(PayAttach payAttach) {
		if (payAttach == null || payAttach.getGoodsId() == null)
			return null;
		return iInnerService.allInfoGoodsId(payAttach.getGoodsId());
	}

	private AssetAllInfoResponse getAssetBaseInfoFromPayOrder(PayOrder payOrder) {
		if (payOrder == null || payOrder.getBusinessRefId() == null)
			return null;
		return iInnerService.allInfoGoodsId(payOrder.getBusinessRefId());
	}

	// 静态
	private AssetAllInfoResponse getAssetBaseInfoFromVIP(PayAttach payAttach) {
		if (payAttach == null || payAttach.getBenefitPackageId() == null)
			return null;
		return iInnerService.benefitPackageBaseInfo(payAttach.getBenefitPackageId());
	}

	/**
	 * 修改 支付表中 附加信息
	 * 
	 * @param payOrder
	 * @return
	 */
	private String SetBusinessAttachByPayOrder(PayOrder payOrder) {
		if (Objects.isNull(payOrder) || Objects.isNull(payOrder.getBusinessRefId())) {
			return null;
		}
		PayOrderBusinessTypeEnum byCode = PayOrderBusinessTypeEnum.getByCode(payOrder.getBusinessType());
		if (Objects.nonNull(byCode) && Objects.nonNull(byCode.getAttachClass()) && byCode.getAttachClass().equals(PayAttach.class)) {
			if (Objects.isNull(payOrder.getBusinessRefId())) {
				return null;
			}
			TransactionResponse tblAssetTransaction = iInnerService.transactionInfo(Longs.tryParse(payOrder.getBusinessRefId()));
			if (Objects.isNull(tblAssetTransaction)) {
				return null;
			}
			PayAttach payAttach = new PayAttach(tblAssetTransaction.getAssetId(), tblAssetTransaction.getGoodsId());
			String businessAttach = JSONObject.toJSONString(payAttach);
			payOrder.setBusinessAttach(businessAttach);
			baseMapper.updateById(payOrder);
			return businessAttach;
		}
		return null;
	}

	@Override
	public Integer getPayStatus(GetPayStatusRequest request) {
		PayOrder payOrder = null;
		if (request.getPayOrderId() != null && request.getPayOrderId() > 0) {
			payOrder = getById(request.getPayOrderId());
		} else if (request.getTransactionId() != null && request.getTransactionId() > 0 && request.getOrderType() != null) {
			OrderTypeEnum orderTypeEnum = OrderTypeEnum.queryConvert(request.getOrderType());
			if (Objects.equals(orderTypeEnum, OrderTypeEnum.PERSONAL_MINT)) {
				payOrder = getByBusiness(PayOrderBusinessTypeEnum.PERSONAL_MINT, String.valueOf(request.getTransactionId()));
			} else if (Objects.equals(orderTypeEnum, OrderTypeEnum.NORMAL)) {
				payOrder = getByBusiness(PayOrderBusinessTypeEnum.NORMAL, String.valueOf(request.getTransactionId()));
			}
		}
		if (payOrder == null) {
			return null;
		}

		PayOrderStatusEnum payOrderStatusEnum = PayOrderStatusEnum.getByCode(payOrder.getPayStatus());
		if (Objects.equals(payOrderStatusEnum, PayOrderStatusEnum.UN_PAY)) {
			PayCenterOrderStatusResponse payCenterOrderStatusResponse = refreshPayOrderStatus(payOrder.getPayOrderId(), String
					.valueOf(payOrder.getAppUserId()), payOrder.getPayMoney(), payOrder.getBusinessAttach());
			if (payCenterOrderStatusResponse != null
					&& (Objects.equals(payCenterOrderStatusResponse.getState(), 3) || Objects.equals(payCenterOrderStatusResponse.getState(), 1))) {
				payOrderStatusEnum = PayOrderStatusEnum.PAYING;
			}
		}
		return payOrderStatusEnum.getCode();
	}

	private PayCenterOrderStatusResponse refreshPayOrderStatus(Long payOrderId, String userId, BigDecimal orderMoney, String businessAttach) {
		boolean isV3 = false;
		String prepayId = null;
		if (StringUtils.isNotBlank(businessAttach)) {
			PayAttach payAttach = JSONUtil.toBean(businessAttach, PayAttach.class);
			if (payAttach != null && Objects.equals(payAttach.getPayCenterVersion(), "v3")) {
				isV3 = true;
				isNull(payAttach.getPrepayId(), ErrorMessage.UNKNOWN_ERROR, () -> {
					log.error("payAttach.prepayId is null.payOrderId:{}", payOrderId);
				});
				prepayId = payAttach.getPrepayId();
			}
		}

		if (isV3) {
			return payCenterV3HttpService.queryPayStatus(payOrderId, userId, prepayId);
		} else {
			return payCenterHttpService.queryPayOrderStatus(payOrderId, userId, orderMoney);
		}
	}

	/**
	 * 根据业务类型和业务关联id获取支付订单
	 *
	 * @param payOrderBusinessTypeEnum
	 * @param businessRefId
	 * @return
	 */
	@Override
	public PayOrder getByBusiness(PayOrderBusinessTypeEnum payOrderBusinessTypeEnum, String businessRefId) {
		QueryWrapper<PayOrder> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("business_type", payOrderBusinessTypeEnum.getCode());
		queryWrapper.eq("business_ref_id", businessRefId);
		return getOne(queryWrapper);
	}

	@Override
	public PayOrderResponse queryPayStatus(Long businessRefId, Integer businessType) {
		MPJLambdaWrapper<PayOrder> query = JoinWrappers
				.lambda(PayOrder.class)
				.eq(PayOrder::getBusinessRefId, businessRefId)
				.eq(PayOrder::getBusinessType, businessType);
		PayOrderResponse one = query.one(PayOrderResponse.class);
		return one;
	}
}
